package com.visualexpress.count;

import java.util.List;

import com.visualexpress.domain.LocationAvertime;
import com.visualexpress.domain.Shipment;
import com.visualexpress.domain.TimeLocation;
import com.visualexpress.dao.LocationAvertimeDAO;
import com.visualexpress.dao.ShipmentDAO;
import com.visualexpress.dao.TimeLocationDAO;
import com.visualexpress.util.DateUtil;

class CountLocationAvertime {
	public static void addShipment(Shipment shipment) {
		TimeLocationDAO timeLocDAO = new TimeLocationDAO();
		LocationAvertimeDAO locAverTimeDAO = new LocationAvertimeDAO();
		List<TimeLocation> timeLocationList = timeLocDAO.findByShipment(shipment);
		
		for(TimeLocation timeLoc : timeLocationList) {
			LocationAvertime locAverTime;
			locAverTime = locAverTimeDAO.findByLocation(timeLoc.getLocation());
			
			if(locAverTime == null) {
				//this location has never been counted
				locAverTime = new LocationAvertime();
				locAverTime.setAmount(1);
				locAverTime.setLocation(timeLoc.getLocation());
				locAverTime.setRecentTime(timeLoc.getArrivalTime());
				locAverTime.setTimeStay(DateUtil.substractInHours(timeLoc.getLeaveTime(), timeLoc.getArrivalTime()));
				locAverTime.setWeight(1.0);
				locAverTimeDAO.save(locAverTime);
			} else {
				double newWeight;
				double diminish;
				//the list must contains only one item
				locAverTime.setAmount(locAverTime.getAmount() + 1);
				if(timeLoc.getArrivalTime().before(locAverTime.getRecentTime())) {
					diminish = Diminish.diminish(DateUtil.substractInDays(locAverTime.getRecentTime(), timeLoc.getArrivalTime()));
					newWeight = 1 * diminish + locAverTime.getWeight();
					locAverTime.setTimeStay((DateUtil.substractInHours(timeLoc
							.getLeaveTime(), timeLoc.getArrivalTime()) * diminish + locAverTime
							.getWeight() * locAverTime.getTimeStay())
							/ newWeight);
				} else {
					diminish = Diminish.diminish(DateUtil.substractInDays(timeLoc.getArrivalTime(), locAverTime.getRecentTime()));
					newWeight = 1 + locAverTime.getWeight() * diminish;
					locAverTime
							.setTimeStay((DateUtil.substractInHours(timeLoc
									.getLeaveTime(), timeLoc.getArrivalTime()) + locAverTime
									.getWeight()
									* locAverTime.getTimeStay() * diminish)
									/ newWeight);
					locAverTime.setRecentTime(timeLoc.getArrivalTime());
				}
				locAverTime.setWeight(newWeight);
				locAverTimeDAO.attachDirty(locAverTime);
			}
		}
	}
}
